﻿#region Using

using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Reflection;

using Common.Enums;

using GameCommon.Base;
using GameCommon.ManagerInterfaces;

#endregion

namespace GameCommon.Manager
{
    public class ScreenManager : IScreenManager
    {
        private readonly ScreenChanger screenChanger;

        private readonly List<ScreenEnum> activeScreens; 

        public ScreenManager()
        {
            this.activeScreens = new List<ScreenEnum>();
            this.screenChanger = new ScreenChanger(this.AddScreen, this.RemoveScreen);
        }

        public IScreen AddScreen(ScreenEnum screen)
        {
           return this.AddScreen(screen, null);
        }

        public IScreen AddScreen(ScreenEnum screenEnum, object argument)
        {
            Debug.WriteLine("Adding screen: {0}", screenEnum);

            if (this.activeScreens.Contains(screenEnum))
            {
                Debug.WriteLine("Screen already added");
                return null;
            }

            this.activeScreens.Add(screenEnum);

            var ass = Assembly.Load("Menu");
            var screenType = ass.GetTypes().FirstOrDefault(x => x.Name == screenEnum.ToString());

            if (screenType != null)
            {
                var screen = this.LoadScreen(screenType, argument);
                Managers.RenderManager.AddScreen(screen);
                return screen;
            }

            ass = Assembly.Load("GameGraphics");
            screenType = ass.GetTypes().FirstOrDefault(x => x.Name == screenEnum.ToString());

            if (screenType != null)
            {
                var screen = this.LoadScreen(screenType, argument);
                Managers.RenderManager.AddScreen(screen);
                return screen;
            }

            return null;
        }

        private void RemoveScreen(ScreenEnum screen)
        {
            Debug.WriteLine("Removing screen: {0}", screen);
            this.activeScreens.Remove(screen);
            Managers.RenderManager.RemoveScreen(screen);
        }

        private IScreen LoadScreen(Type screenType, object argument)
        {
            var screen = (IScreen)Activator.CreateInstance(screenType, this.screenChanger, argument);
            screen.Initialize();
            screen.LoadContent();
            return screen;
        }
    }
}